package com.qiaofang.housewarehouse.facade.interceptor;

import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

/**
 * 类描述: 日志拦截器，打印controller层的入参和出参<br>
 * 创建时间: 2016/7/29 0029 <br>
 *
 * @author 李恒
 */
@Aspect
@Component
public class ControllerAspect {
	private Logger logger = null;

	/**
	 * Controller aspect.
	 */
	@Pointcut("execution(* com.qiaofang.housewarehouse.facade.impl.*.*(..))")
	public void controllerAspect() {
	}

	/**
	 * Around 手动控制调用核心业务逻辑，以及调用前和调用后的处理,
	 * <p>
	 * 注意：当核心业务抛异常后，立即退出，转向AfterAdvice 执行完AfterAdvice，再转到ThrowingAdvice
	 *
	 * @param pjp
	 *            the pjp
	 * @return object
	 * @throws Throwable
	 *             the throwable
	 */
	@Around(value = "controllerAspect()")
	public Object aroundAdvice(ProceedingJoinPoint pjp) throws Throwable {
		// 1.入参打印
		String className = pjp.getSignature().getDeclaringTypeName();
		logger = LoggerFactory.getLogger(className);
		List<String> methodParams = new ArrayList<>();

		if (pjp.getArgs().length > 0) {
			for (Object o : pjp.getArgs()) {
				if (o == null) {
					continue;
				}
				methodParams.add(ToStringBuilder.reflectionToString(o, ToStringStyle.SHORT_PREFIX_STYLE));
			}
		}
		logger.info("request:{}", methodParams.toString());

		long startTime = System.currentTimeMillis();
		try {
			Object response = pjp.proceed();
			// 2.打印出参，返回结果
			long endTime = System.currentTimeMillis();
			// 3.出参打印
			logger.info("reponse:cost={}ms,message={}", endTime - startTime, response != null ? ToStringBuilder.reflectionToString(response, ToStringStyle.SHORT_PREFIX_STYLE) : "");
			return response;
		} catch (Throwable e) {
			long endTime = System.currentTimeMillis();
			logger.error("reponse:cost={}ms", endTime - startTime, e);
			throw e;
		}
	}

}
